import React, {
    Component,
    Fragment,
    createContext,
    useContext,
    useReducer,
    useState,
    useEffect,
    useCallback,
    useMemo,
    useRef
} from 'react'

import CounterComponent from '@/components/counter'
import ShowAreaComponent from '@/components/showArea'
import ButtonsComponent from '@/components/buttons'
import ColorComponent from '@/components/color'
//= ======== useState============

const UseStateComponent = () => {
    const [count, setCount] = useState(0)
    const [istrue, setIstrue] = useState(true)
    const handleChange = () => {
        setIstrue(!istrue)
    }
    return (
        <>
            <h2>==========1、useState========</h2>
            {istrue ? <h1>{count}</h1> : ''}
            <button onClick={handleChange}>change</button>
            <button
            onClick={() => {
                    setCount(count + 1)
                }}>
                +
            </button>
      </>
    )
}
//= ======== useEffect ============

const UseEffectComponent = () => {
    const [width, setWidth] = useState(window.innerWidth)
    const [count, setCount] = useState(1)
    const [num, setNum] = useState(2)

    const resizeHandle = () => {
        setWidth(window.innerWidth)
        console.log(window.innerWidth)
    }
    useEffect(() => {
        console.log('定义事件接口')
        window.addEventListener('resize', resizeHandle)
        return () => {
            console.log('注销事件接口')
            window.removeEventListener('resize', resizeHandle)
        }
    }, [width])
    useEffect(() => {
        console.log('count状态更新')
        return () => {
            console.log('useEffect卸载')
        }
    }, [count])
    return (
        <>
            {console.log('渲染')}
            <h2>==========2、useEffect========</h2>
            <h1>{width}</h1>
        <p>第二个参数count 只有传入count的useEffect 才会执行</p>
        <h1>{count}</h1>
            <button
            onClick={() => {
                    setCount(count + 1)
                }}>
                count+
          </button>
        <h1>{num}</h1>
        <button
                onClick={() => {
                    setNum(num + 1)
                }}>
                num+
          </button>
      </>
    )
}
//= ======== userContext============
export const CountContext = createContext()
const UseContextComponent = () => {
    const [count, setCount] = useState(0)
    return (
        <>
        <h2>==========3、useContext========</h2>
            <p>
                You clicked
            {count}
            {' '}
                times
          </p>
            <button
            onClick={() => {
                    setCount(count + 1)
                }}>
                click me
          </button>
        <CountContext.Provider value={count}>
              <CounterComponent />
            </CountContext.Provider>
      </>
    )
}
// ============= useReducer =============
const initialCount = 0
function init(initialCount) {
    return { count: initialCount }
}

const reducer = (state, action) => {
    switch (action.type) {
        case 'increment':
            return { count: state.count + 1 }
        case 'decrement':
            return { count: state.count - 1 }
        case 'reset':
            return init(action.payload)
        default:
            throw new Error()
    }
}

const UseReducerComponent = () => {
    const [state, dispatch] = useReducer(reducer, initialCount, init)
    return (
        <>
            <h2>==========4、useReducer========</h2>
            Count: 
{' '}
{state.count}
        <button onClick={() => dispatch({ type: 'reset', payload: initialCount })}>
                Reset
            </button>
        <button onClick={() => dispatch({ type: 'increment' })}>+</button>
            <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
      </>
    )
}

//= ========== 实例 =============

const Example = () => (
    <>
    <h2>==========5、实例========</h2>
    <ColorComponent>
            <ShowAreaComponent />
        <ButtonsComponent />
      </ColorComponent>
  </>
)

//= =========== useCallback =============

const CallbackComponent = () => {
    const [count, setCount] = useState(1)
    const [num, setNum] = useState(1)

    const memoized = useCallback(() => num + 100, [count])

    return (
        <>
            <h2>==========6、useCallback========</h2>
            <button
            onClick={() => {
                    setCount(count + 1)
                }}>
                count+
            </button>
            <button
            onClick={() => {
                    setNum(num + 1)
                }}>
                num+
          </button>
        <p>
                count记忆值:
              {memoized()}
                <em>始终返回的是useCallback里计算的值num+100</em>
            </p>
            <p>
                num原始值:
            {num}
            </p>
      </>
    )
}

//= ============  useMemo =============

const UseMemoComponent = () => {
    const [xiaohong, setXiaohong] = useState('小红待客状态')
    const [zhiling, setZhiling] = useState('志玲待客状态')
    return (
        <>
            <h2>==========7、useMemo========</h2>
        <button
                onClick={() => {
                    setXiaohong(new Date().getTime())
                }}>
                小红
            </button>
        <button
                onClick={() => {
                    setZhiling(`${new Date().getTime()},志玲向我们走来了`)
                }}>
                志玲
            </button>
        <ChildComponent name={xiaohong}>{zhiling}</ChildComponent>
      </>
    )
}
function ChildComponent({ name, children }) {
    function changeXiaohong(name) {
        console.log('她来了，她来了。小红向我们走来了')
        return `${name},小红向我们走来了`
    }
    // const actionXiaohong = changeXiaohong(name);
    const actionXiaohong = useMemo(() => changeXiaohong(name), [name])
    return (
        <>
            <div>{actionXiaohong}</div>
            <div>{children}</div>
      </>
    )
}

//= ========== useRef===========

const UseRefComponent = () => {
    const inputRef = useRef(null)
    /*   useEffect(() => {
        inputRef.current.focus();
    }); */
    const onButtonClick = () => {
        inputRef.current.value = 'Hello Hooks'
        console.log(inputRef) // 输出获取到的DOM节点
    }

    // 类似修改state值一样，输入内容的时候保存变量
    const [text, setText] = useState('Hello UseRef')
    const textRef = useRef()
    useEffect(() => {
        textRef.current = text
        console.log('textRef.current:', textRef.current)
    })
    return (
        <>
            <h2>==========8、useRef========</h2>
        <input ref={inputRef} type="text" />
            <button onClick={onButtonClick}>input里填充文字</button>
            <br />
        <br />
        <input
                value={text}
            onChange={e => {
                    setText(e.target.value)
                }}/>
            {/* 类似修改state值一样，输入内容的时候保存变量 */}
      </>
    )
}

//= ========== 自定义hooks===========

const useCount = num => {
    const [count, setCount] = useState(num)
    return [count, () => setCount(count + 1), () => setCount(count - 1)]
}
const CustomComponent = () => {
    const [count, addCount, redCount] = useCount(1)

    return (
        <>
            <h2>==========9、自定义hooks========</h2>
        <p>必须use开头并且在函数内部调用其他hooks，也就相当于抽离出来hooks</p>
            <h1>{count}</h1>
            <button onClick={addCount}> + </button>
        <button onClick={redCount}> - </button>
      </>
    )
}
const Hooks = () => (
    <div style={{ margin: '50px' }}>
    <UseStateComponent />
        <UseEffectComponent />
    <UseContextComponent />
    <UseReducerComponent />
    <Example />
    <CallbackComponent />
        <UseMemoComponent />
    <UseRefComponent />
        <CustomComponent />
  </div>
)
export default Hooks
